package com.yzmoney.wechat.service;

import com.yzmoney.common.constant.Constants;
import com.yzmoney.common.constant.PropertyUtils;
import com.yzmoney.common.service.SaveQrcodeLogService;
import com.yzmoney.common.service.SaveUserService;
import com.yzmoney.common.service.StaticService;
import com.yzmoney.common.util.JDKStackTrace;
import com.yzmoney.common.util.JsonUtils;
import com.yzmoney.wechat.model.reply.Item;
import com.yzmoney.wechat.model.reply.ReplyImageMsg;
import com.yzmoney.wechat.model.reply.ReplyNewsMsg;
import com.yzmoney.wechat.model.reply.ReplyTextMsg;
import net.sf.json.JSONObject;
import org.apache.commons.lang3.StringUtils;
import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;

import javax.annotation.Resource;
import java.util.*;

/**
 * 接收事件消息
 *
 * 以后做成公共平台最好是传一个参数 WechatType中的枚举类型
 *
 * @author DOVE
 */
@Service
public class WechatEventReceiveService {
    private static Logger logger = Logger.getLogger(WechatEventReceiveService.class);

    @Autowired
    private SaveUserService saveUserService;

    @Autowired
    private View jaxb2MarshallingView;

    @Autowired
    private SaveQrcodeLogService saveQrcodeLogService;
    @Autowired
    private WechatUserService wechatUserService;

    @Resource
    private StaticService staticService;

    final private static String SUBSCRIBE_TEM = "/wechat/gzh/subscribe.ftl";

    final private static String SCAN_TEM = "/wechat/gzh/scan.ftl";

    public ModelAndView receiveEvent(Document docXml) throws Exception {
        ModelAndView mav = null;
        Element rootElement = docXml.getRootElement();
        Element eventElement = rootElement.element("Event");
        String event = eventElement.getTextTrim();

        if (event.equals("subscribe")) {//关注
            mav = receiveSubscribeEvent(rootElement);
        } else if (event.equals("unsubscribe")) {//取消关注
            mav = receiveUnSubscribeEvent(rootElement);
        } else if (event.equals("CLICK")) {//菜单click事件
            mav = receiveClickEvent(rootElement);
        } else if(event.equals("SCAN")){
            mav = receiveScanEvent(rootElement);
        }
        return mav;
    }

    /**
     * 接受scan事件信息
     * @param rootElement
     * @return
     */
    private ModelAndView receiveScanEvent(Element rootElement){
        Element fromUserNameElement = rootElement.element("FromUserName");
        Element toUserNameElement = rootElement.element("ToUserName");
        Element ticketElement = rootElement.element("Ticket");
        String fromUserName = toUserNameElement.getTextTrim();
        String toUserName = fromUserNameElement.getTextTrim();
        String ticket = "";
        if(ticketElement != null){
            ticket = ticketElement.getTextTrim();
        }
        logger.info(Constants.LOGPRIFIX + "event:scan ,fromUserName=" + fromUserName + ",toUserName=" + toUserName + ",ticket=" + ticket);
        saveSubscriberOrScanLog(fromUserName, toUserName, ticket, 1);

        ModelAndView xmlMAV = new ModelAndView(jaxb2MarshallingView);
        ReplyTextMsg replyTextMsg = new ReplyTextMsg();
        replyTextMsg.setFromUserName(fromUserName);
        replyTextMsg.setToUserName(toUserName);
        Map map = new HashMap<String, Object>();
        if(StringUtils.isNotEmpty(ticket)){
            map.put("ticket",ticket);
        }
        String content = staticService.build(SCAN_TEM,map);

        replyTextMsg.setContent(content);
        replyTextMsg.setCreateTime(new Date().getTime());
        xmlMAV.addObject(replyTextMsg);
        return xmlMAV;
    }

    /**
     * 用户关注后回复消息
     *
     * @param rootElement
     * @return
     */
    private ModelAndView receiveSubscribeEvent(Element rootElement) {
        Element fromUserNameElement = rootElement.element("FromUserName");
        Element toUserNameElement = rootElement.element("ToUserName");
        Element ticketElement = rootElement.element("Ticket");
        String fromUserName = toUserNameElement.getTextTrim();
        String toUserName = fromUserNameElement.getTextTrim();
        String ticket = "";
        if(ticketElement != null){
            ticket = ticketElement.getTextTrim();
        }
        logger.info(Constants.LOGPRIFIX + "event:subscribe ,fromUserName=" + fromUserName + ",toUserName=" + toUserName + ",ticket=" + ticket);
        saveSubscriberOrScanLog(fromUserName, toUserName, ticket, 0);
        ModelAndView xmlMAV = new ModelAndView(jaxb2MarshallingView);

        ReplyNewsMsg replyNewsMsg = new ReplyNewsMsg();
        replyNewsMsg.setFromUserName(fromUserName);
        replyNewsMsg.setToUserName(toUserName);
        replyNewsMsg.setCreateTime(new Date().getTime());
        replyNewsMsg.setArticleCount(1);
        List<Item> items = new ArrayList<>();
        Item item = null;
        Map map = new HashMap<String, Object>();
        if(StringUtils.isNotEmpty(ticket)){
            map.put("ticket",ticket);
        }
        String content = staticService.build(SUBSCRIBE_TEM,map);
        JSONObject itemObject = JSONObject.fromObject(content);
        item = new Item();
        item.setUrl(itemObject.getString("url"));
        item.setPicUrl(itemObject.getString("picUrl"));
        item.setTitle(itemObject.getString("title"));
        item.setDescription(itemObject.getString("description"));
        items.add(item);
        replyNewsMsg.setItems(items);
        xmlMAV.addObject(replyNewsMsg);

        //用户关注时，保存用户信息
        try {
            saveUserService.saveUserInfo(toUserName);
        }catch (Exception e){
            logger.info("保存用户信息失败：" + toUserName + "," + JDKStackTrace.getJDKStrack(e));
        }

        return xmlMAV;
    }

    /**
     * 用户取消关注 事件
     *
     * @param rootElement
     * @return
     */
    private ModelAndView receiveUnSubscribeEvent(Element rootElement) {
        Element fromUserNameElement = rootElement.element("FromUserName");
        Element toUserNameElement = rootElement.element("ToUserName");
        String fromUserName = toUserNameElement.getTextTrim();
        String openId = fromUserNameElement.getTextTrim(); //openId

        logger.info(Constants.LOGPRIFIX + "fromUserName=" + fromUserName + ",openId=" + openId);

        //用户取消关注时，更新用户信息
        saveUserService.cancelSubscriber(openId);

        return new ModelAndView("forward:/gzh/noReply.do");
    }

    /**
     * 回复click事件
     *
     * @param rootElement
     * @return
     */
    private ModelAndView receiveClickEvent(Element rootElement) {
        Element fromUserNameElement = rootElement.element("FromUserName");
        Element toUserNameElement = rootElement.element("ToUserName");
        Element eventKeyElement = rootElement.element("EventKey");
        String fromUserName = toUserNameElement.getTextTrim();
        String toUserName = fromUserNameElement.getTextTrim();
        String key = eventKeyElement.getTextTrim();

        logger.info(Constants.LOGPRIFIX + "fromUserName=" + fromUserName + ",toUserName=" + toUserName + ",key=" + key);

        ModelAndView xmlMAV = new ModelAndView(jaxb2MarshallingView);
        ReplyTextMsg replyTextMsg = new ReplyTextMsg();
        replyTextMsg.setFromUserName(fromUserName);
        replyTextMsg.setToUserName(toUserName);
        //如果点击的按钮的key是XXXXX
        if (StringUtils.equals(key, "XXXXX")) {
            replyTextMsg.setContent("XXXX");
            replyTextMsg.setCreateTime(new Date().getTime());
            xmlMAV.addObject(replyTextMsg);
        }
        return xmlMAV;
    }

    private void saveSubscriberOrScanLog(String wechatName,String openId,String ticket,Integer accessType){
        Map param = new HashMap();
        param.put("wechatName", wechatName);
        param.put("openId", openId);
        param.put("ticket", ticket);
        param.put("accessType", String.valueOf(accessType));
        try{
            saveQrcodeLogService.saveQrcodeInfo(param);
        }catch (Exception e){
            logger.info("二维码信息保存失败：" + JDKStackTrace.getJDKStrack(e));
        }

    }

}
